Projekt Pronal Projekt Pronal

Kazalo:
Sofinasiranje projekta
Starejši - učbenik...
Tekmovanja...
Tekmovanja - dopolni...
Tekmovanja - Parsons...
Tekmovanja - popravi...
Starejši - zbirka nalog
Funkcije
If stavek
Izpisi
Množice
Nizi
Pisanje in popravljanje programa
Seznami in nizi
Slovarji
Spoznajmo Python
Uvod v funkcije
Zanka for
Zanka while
Seznami in nizi

Seznami in nizi


Dis... kva že?

Jeremija ves svoj prosti čas (torej ko ne spi, ko ne toži nad bolečinami, skratka kako minuto na dan) preživi kot moderator na nekem manj znanem forumu, ki ima kar lepo število registriranih uporabnikov, vendar večina med njimi piše same neumnosti. Med takimi je še posebno dejaven Tomaž Majer. Če se zdi Jeremiji objava žaljiva, jo nemudoma zbriše. Če objava na forumu ni žaljiva, ampak je le precej neumna, pa naredi naslednje: Vse samoglasnike odstrani iz besedila in jih (v enakem vrstnem redu) doda nazaj na konec. Na primer sporočilo:

Banana je najboljša! Izjemno dobra je tudi v kombinaciji z Nutelo!

postane

Bnn j njbljš! zjmn dbr j td v kmbncj z Ntl!aaaeaoaIeooaeuioiaiiueo

Takó besedilo postane težko berljivo in večina bralcev ga ignorira. Če pa se najde kdo, ki ga vsebina resnično zanima, lahko z nekaj truda razvozla vsebino sporočila.

Opisana transformacija besedila je znana pod imenom disemvoweling.

1. podnaloga

Napišite funkcijo prvi_samoglasnik(niz), ki kot argument dobi niz niz in vrne položaj (indeks) prvega samoglasnika v danem nizu. Če v nizu ni samoglasnika, vrni -1.

  >>> prvi_samoglasnik('Krščen matiček!')
  4

Uradna rešitev

def prvi_samoglasnik(niz):
    """Vrne položaj (indeks) prvega samoglasnika v danem nizu."""
    samoglasniki = "aeiouAEIOU"
    kje = 0
    for znak in niz:
        if znak in samoglasniki: # takoj pri prvem bomo zaključili zadevo
            return kje
        kje += 1
    return -1 # ni ga bilo

2. podnaloga

Napišite funkcijo disemvowel(sporocilo), ki kot argument prejme niz sporocilo. Funkcija naj sestavi in vrne nov niz, ki ga dobi iz niza sporocilo tako, da vse samoglasnike prestavi na konec niza.

  >>> disemvowel('Banana je dobra!')
  'Bnn j dbr!aaaeoa'

Uradna rešitev

def disemvowel(sporocilo):
    """Desemvowlanje sporočila."""
    brez = '' # niz brez samoglasnika
    samoglasniki = '' # vsi samoglasniki iz niza
    for c in sporocilo:
        if c in 'aeiouAEIOU': # gre za samoglasnik
            samoglasniki += c
        else: #"običajni" znak
            brez += c
    return brez + samoglasniki #zlepimo v pravem redu

3. podnaloga

Včasih pa želimo sporočilo dešifrirati, saj nas zanima njegova vsebina. Ta naloga je vse prej kot enostavna, saj ne vemo kam točno je treba vriniti izgnane samoglasnike. Sporočilo 'Bnn j dbr!aaaeoa' bi lahko dešifrirali tudi kot 'Banna ja debora!', kot 'Bnana aje dobar!' ipd.

Bob Rock je na mesta v besedilu, kjer predvideva, da bi morali stati samoglasniki, vstavil znake '*' (zvezdica). V sporočilu zvezdica nikoli ne bo imela drugega pomena. Prav tako bo število samoglasnikov enako številu zvezdic in vsi samoglasniki bodo na koncu niza.

Napišite funkcijo razveljavi_disemvowel(niz), ki bo zvezdice v nizu nadomestila s samoglasniki, ki se v nizu niz nahajajo na koncu. Zgled:

  >>> razveljavi_disemvowel('B*n*n* j* d*br*!aaaeoa')
  'Banana je dobra!'

Uradna rešitev

def razveljavi_disemvowel(niz):
    """Zvezdice v disemvowlanem nizu nadosmesti s samoglasniki s konca niza."""
    samoglasnik = 'aeiouAEIOU'
    seznam_samoglasnikov = [x for x in niz if x in samoglasnik]
    stevec_samoglasnikov = 0
    nov_niz = ''
    for znak in niz:
        if znak == '*':
            nov_niz += (seznam_samoglasnikov[stevec_samoglasnikov])
            stevec_samoglasnikov += 1
        elif znak in samoglasnik: #smo prišli do konca
            break
        else:
            nov_niz += znak
    return nov_niz

Analiza besedila

Pri tej nalogi bomo analizirali nize, ki predstavljajo pravilno slovensko oblikovane besede in stavke. Pri vseh podnaloge lahko predpostavite, da so vhodni nizi s dobro oblikovani, tj. ne vsebujejo dveh zaporednih presledkov oz. nepotrebnih presledkov ter prelomov vrstice na začetku ali na koncu.

1. podnaloga

Sestavite funkcijo stevilo_besed(niz), ki v podanem nizu prešteje število besed, pri čemer lahko predpostavite, da presledki stojijo natanko pred vsako (razen prvo) besedo v nizu. Zgled:

  >>> stevilo_besed('Višje, hitreje, močneje!')
  3

Uradna rešitev

def stevilo_besed(niz):
    """V danem nizu prešteje število besed"""
    st_besed = 1 #štejemo prvo
    if len(niz) == 0: # vendar je mogoče sploh ni
        return 0
    for znak in niz:
        if znak == ' ':
            st_besed += 1
    return st_besed

2. podnaloga

Sestavite funkcijo samoglasniki(niz), ki v podanem nizu niz prešteje število samoglasnikov. Zgled:

>>> samoglasniki('pomaranča')
4

Uradna rešitev

def samoglasniki(niz):
    """Prešteje in vrne število samoglasnikov v danem nizu"""
    st_samoglasnikov = 0
    samoglasniki = 'aeiouAEIOU'
    for znak in niz:
        if znak in samoglasniki:
            st_samoglasnikov += 1
    return st_samoglasnikov

3. podnaloga

V Pythonu vrstice večvrstičnega niza ločujemo z znakom '\n'. Sestavite funkcijo vrstice(s), ki sprejme večvrstični niz s in vrne seznam, ki vsebuje vse vrstice tega niza (v istem vrstnem redu). Zgled:

  >>> vrstice("Danes\n je lep\ndan.\n")
  ['Danes', ' je lep', 'dan.', '']

Opomba: Python obravnava niz '\n' kot en sam znak.

Uradna rešitev

def vrstice(niz):
    """Vrne seznam vrstic v danem nizu"""
    return niz.split('\n')

4. podnaloga

Haiku (japonsko 俳句) je japonska pesniška oblika iz treh verzov (vrstic), ki obsega sedemnajst zlogov. Prvi in tretji verz imata po pet zlogov, drugi sedem.

Na kulturnem natečaju TomoHaiku udeleženci oddajajo svoje izdelke na strežnik Tomo. Napišite kontrolno funkcijo haiku(s), ki sprejme niz s, ter vrne True, če niz ustreza pesniški obliki haiku, sicer pa vrne False.

Predpostavite lahko, da število samoglasnikov v neki besedi ustreza številu njenih zlogov, ter da niz s ne vsebuje nepotrebnih začetnih oz. končnih praznih vrstic. Vrstice so ločene z znakom za prelom vrstice '\n'. Primer:

  >>> haiku('Skrit v svojem svetu,\ntemna otožnost neba,\ntvoj topli objem.')
  True
  >>> haiku('Riba,\nraca, rak,\nvinjak je grenak!')
  False

Uporabite lahko katero od funkcij, ki ste jih napisali v prejšnjih podnalogah.

Uradna rešitev

def haiku(besedilo):
    """Preveri, ali je v podanem nizu zapisan validen haiku"""
    if besedilo.count('\n') != 2: # najprej preštejemo vrstice
        return False
    i = besedilo.find('\n') # konec prve vrstice
    j = besedilo.find('\n', i + 1) # konec druge
    # prva in tretja morate imeti 5, srednja pa 7 samoglasnikov
    return samoglasniki(besedilo[:i]) == samoglasniki(besedilo[j:]) == 5 and samoglasniki(besedilo[i:j]) == 7

5. podnaloga

Sestavite funkcijo podcrtaj(niy), ki za parameter dobi niz niz, v katerem so podnizi, ki bi morali biti izpisani podčrtano, označeni s podčrtajem na začetku in na koncu. Če je v nizu liho mnogo podčrtajev, si mislite, da je še eden na koncu. Funkcija naj vrne dvovrstični niz, kjer je v prvi vrstici originalni niz niz toda brez podčrtajev, sledi znak za prelom vrstice, naslednjo vrstico pa sestavlja niz, sestavljen iz presledkov in minusov, pri čemer minusi ležijo pod tistimi deli besedila, ki morajo biti podčrtani. Primer:

>>> podcrtaj("Jaz _sem_ pa cajzelc!")
'Jaz sem pa cajzelc!\n    ---            '

Predpostavite, da v nizu ni nobenega znaka '\n'.

Uradna rešitev

def podcrtaj(niz):
    '''Vrne niz iz dveh vrstic, kjer so ustrezni znaki podčrtani'''
    prva_vrsta = ''
    druga_vrsta = ''
    podcrtujem = False  # ali so trenutni znaki podčrtani
    for znak in niz:
        if znak == '_': # preklopimo način podčrtovanja
            podcrtujem = not podcrtujem
        else:
            prva_vrsta += znak # v prvi vrsti so vsi znaki razen podčrtajev
            if podcrtujem: # v drugi pa bodisi presledki, bodisi podčrtaji
                druga_vrsta += '-'
            else:
                druga_vrsta += ' '
    return prva_vrsta + '\n' + druga_vrsta

6. podnaloga

Sestavite funkcijo stevilo_znakov(niz), ki v podanem nizu niz prešteje število znakov, pri čemer se presledki ne upoštevajo. Zgled:

  >>> stevilo_znakov('B     u!')
  3

Uradna rešitev

def stevilo_znakov(niz):
    """Prešteje in vrne število znakov, presledki se ne upoštevajo"""
    st_znakov = sum(1 for znak in niz if znak != ' ')
    return st_znakov

7. podnaloga

Sonet je priljubljena pesniška oblika. Sestavljen je iz štirih kitic, pri čemur med vsakima dvema kiticama avtor izpusti eno prazno vrstico. Prvi dve kitici sta štirivrstični — kvartini, drugi dve pa sta trivrstični — tercini.

V slovenskem sonetu je standardni verz italijanski (laški) ali jambski enajsterec. To pomeni, da v vsaki vrstici nastopa natanko enajst zlogov.

Na kulturnem natečaju TomoSonet udeleženci oddajajo svoje izdelke na strežnik Tomo. Napiši kontrolno funkcijo sonet(besedilo), ki sprejme niz besedilo, ter vrne True, če niz ustreza slovenskemu sonetu, in False sicer. Zgled:

>>> sonet('Bolj slab\nsonet.\n\nZa umret!')
False

Namig: V slovenskem jeziku število samoglasnikov v neki besedi ustreza številu njenih zlogov. (Obstaja nekaj izjem, ki pa jih bomo zanemarili.)

Uradna rešitev

def sonet(besedilo):
    """Preveri validnost danega soneta in vrne True/False"""
    # preverimo najprej, če je dovolj vrstic
    if sum(1 for znak in besedilo if znak == '\n') != 16:
        return False
    seznam_vrstic = besedilo.split('\n')
    if not seznam_vrstic[4] == seznam_vrstic[9] == seznam_vrstic[13] == '':
        return False #ni praznih vrstic na ustreznih mestih

    seznam_nepraznih_vrstic = [vrstica for vrstica in seznam_vrstic if vrstica != '']
    # preverimo za vsako vrstico, če ima zadostno število samoglasnikov
    for vrstica in seznam_nepraznih_vrstic:
        if samoglasniki(vrstica) != 11:
            return False
    return True # prišli smo čez vse teste

Ujemanja

1. podnaloga

Sestavite funkcijo zacetek(a, b), ki bo za niza a in b preštela, v koliko začetnih znakih se ujemata.

Niza nimata nujno enakega začetka, lahko se delno ujemata na začetku, lahko se en niz v celoti pojavi na začetku drugega, ali pa sta niza celo enaka. Ni potrebno obravnavati vsakega od teh primerov posebej, samo pazite, da bo funkcija delala pravilno za vse primere.

  >>> zacetek('matematika', 'fizika')
  0
  >>> zacetek('matematika', 'matija')
  3
  >>> zacetek('oder', 'oderuh')
  4
  >>> zacetek('izpit', 'izpit')
  5

Pri rešitvi obvezno uporabite zanko while, ne pa for.

Uradna rešitev

def zacetek(a, b):
    """Prešteje in vrne koliko začetnih znakih se ujemata niza a in b"""
    stevec = 0
    dolzina_krajsega = min(len(a), len(b))
    while stevec < dolzina_krajsega and a[stevec] == b[stevec]:
        stevec += 1
    return stevec

2. podnaloga

Sestavite funkcijo zacetekFor(a, b), ki bo za niza a in b preštela, v koliko začetnih znakih se ujemata.

Pri rešitvi ne smete uporabiti zanke while.

Uradna rešitev

def zacetekFor(a, b):
    """Prešteje in vrne koliko začetnih znakih se ujemata niza a in b"""
    najkrajsi = min(len(a),len(b))
    for i in range(najkrajsi): # ustaviti se moramo, ko krajšega niza zmanjka
        if a[i] != b[i]:
            return i # i-ti znak je prvi neujemajoči, ker štejemo od 0 dalje ...
    return najkrajsi # ujemala sta se v vseh

3. podnaloga

Napiši funkcijo st_ujemanj(beseda1, beseda2), ki prejme dve besedi in vrne število znakov, v katerih se besedi ujemata.

Primeri:

  >>> st_ujemanj("ROKA", "ROKAV")
  4
  >>> st_ujemanj("CELINKE", "POLOVINKE")
  1

Uradna rešitev

def st_ujemanj(beseda1, beseda2):
    """Prešteje in vrne, koliko istoležnih znakov je enakih"""
    ujemanja = 0
    for i in range(min(len(beseda1), len(beseda2))): # zanka se izvede tolikokrat koliko je dolga najkrajsa beseda b1 oz. b2
        if beseda1[i] == beseda2[i]: # ce sta znaka v obeh besedah enaka, se ujemanje poveca za 1.
            ujemanja += 1
    return ujemanja

4. podnaloga

Napiši funkcijo ujeme(beseda1, beseda2), ki kot vhod prejme dve besedi b1 in b2, ter vrne novo besedo, ki vsebuje tiste znake, v katerih se besedi ujemata (imata na istem mestu isti znak), znaki na ostalih mestih pa so zamenjane s pikami. Če besedi nista enako dolgi, naj bo nova beseda toliko dolga, kolikor je dolga krajša izmed podanih besed.

Primeri:

  >>> ujeme("ROKA", "REKE")
  'R.K.'
  >>> ujeme("ROKA", "ROKAV")
  'ROKA'

Uradna rešitev

def ujeme(beseda1, beseda2):
    """Vrne niz, kjer je s pikami označeno, v katerih znakih se besedi ne ujemata"""
    rezultat = ""
    for i in range(min(len(beseda1), len(beseda2))):
        if beseda1[i] == beseda2[i]:      # ce sta znaka enaka
            rezultat += beseda1[i]   # potem v rezultat dodamo ta znak
        else:
            rezultat += "."  # sicer dodamo piko.
    return rezultat
Mesto objave ob koncu projekta 15.9.2018